package buildinjava.java.compiler;

import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import java.io.File;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;

/**
 * Caches dependency information.
 *
 * @author Gili Tzabari
 */
public class DependencyCache implements Serializable
{
	/**
	 * Maps a file to its node.
	 */
	public Map<File, FileNode> files = new MapMaker().makeComputingMap(new CreateFileNode());
	/**
	 * Maps a class binary name to its node.
	 */
	public Map<String, ClassNode> classes = new MapMaker().makeComputingMap(new CreateClassNode());

	/**
	 * Information about a file.
	 */
	public static class FileNode implements Serializable
	{
		/**
		 * The last time the file was compiled, in milliseconds since .
		 */
		public long lastCompiled;
		/**
		 * The binary names of classes defined by the file.
		 */
		public Set<String> classes = Sets.newHashSet();

		@Override
		public String toString()
		{
			return getClass().getName() + "[lastCompiled=" + lastCompiled + " , classes=" + classes + "]";
		}
	}

	/**
	 * Creates a new FileNode.
	 */
	private static class CreateFileNode implements Function<File, FileNode>, Serializable
	{
		@Override
		public FileNode apply(File from)
		{
			return new FileNode();
		}
	}

	/**
	 * Information about a class.
	 */
	public static class ClassNode implements Serializable
	{
		/**
		 * Binary names of classes that this class depends on.
		 */
		public Set<String> dependencies = Sets.newHashSet();

		@Override
		public String toString()
		{
			return getClass().getName() + "[dependants=" + dependencies + "]";
		}
	}

	@Override
	public String toString()
	{
		return getClass().getName() + "[files=" + files + ", classes=" + classes + "]";
	}

	/**
	 * Creates a new ClassNode.
	 */
	private static class CreateClassNode implements Function<String, ClassNode>, Serializable
	{
		@Override
		public ClassNode apply(String from)
		{
			return new ClassNode();
		}
	}
}
